package Example;

import java_cup.runtime.SymbolFactory;
%%
%cup
%class Scanner
%{
	public Scanner(java.io.InputStream r, SymbolFactory sf){
		this(r);
		this.sf=sf;
	}
	private SymbolFactory sf;
%}
%eofval{
    return sf.newSymbol("EOF",sym.EOF);
%eofval}


LineTerminator = \r|\n|\r\n

/* comments */
TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*" + "/"
EndOfLineComment     = "//" .* {LineTerminator}
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*


Identifier = [:jletter:][:jletterdigit:]*
DecIntegerLiteral = [0-9]+
StringLiteral = "\"" [^\"] ~"\""

%%

"ref" { return sf.newSymbol("REF",sym.REF); }
"readln" { return sf.newSymbol("READLN",sym.READLN); }
"read" { return sf.newSymbol("READ",sym.READ); }
"println" { return sf.newSymbol("PRINTLN",sym.PRINTLN); }
"print" { return sf.newSymbol("PRINT",sym.PRINT); }
"inc" { return sf.newSymbol("INC",sym.INC); }
"dec" { return sf.newSymbol("DEC",sym.DEC); }
"int" { return sf.newSymbol("Integer",sym.INT); }
"string" { return sf.newSymbol("String",sym.STRING); }
"boolean" { return sf.newSymbol("Boolean",sym.BOOLEAN); }
"void" { return sf.newSymbol("Void",sym.VOID); }
"if" { return sf.newSymbol("IF",sym.IF); }
"else" { return sf.newSymbol("ELSE",sym.ELSE); }
"while" { return sf.newSymbol("WHILE",sym.WHILE); }
"return" { return sf.newSymbol("RETURN",sym.RETURN); }

{DecIntegerLiteral} { return sf.newSymbol("Integral Number",sym.VALINT, new Integer(yytext())); }
"true" | "false" { return sf.newSymbol("Boolean Number",sym.VALBOOL, Boolean.parseBoolean(yytext())); }
{StringLiteral} { return sf.newSymbol("String",sym.VALSTR, yytext()); }

{TraditionalComment} {/* ignore */}
{EndOfLineComment} {/* ignore */}
{DocumentationComment} {/* ignore */}

"," { return sf.newSymbol("Colon",sym.COMMA); }
";" { return sf.newSymbol("Semicolon",sym.SEMI); }
"(" { return sf.newSymbol("Left Bracket",sym.LPAREN); }
")" { return sf.newSymbol("Right Bracket",sym.RPAREN); }
"{" { return sf.newSymbol("Left Bracket",sym.LBRACKETS); }
"}" { return sf.newSymbol("Right Bracket",sym.RBRACKETS); }
"[" { return sf.newSymbol("Square Left Bracket",sym.SLBRACKETS); }
"]" { return sf.newSymbol("Square Right Bracket",sym.SRBRACKETS); }

"-" { return sf.newSymbol("MINUS",sym.MINUS); }
"+" { return sf.newSymbol("Plus",sym.PLUS); }
"*" { return sf.newSymbol("Times",sym.TIMES); }
"/" { return sf.newSymbol("Divided",sym.DIVIDE); }

"!"  { return sf.newSymbol("NOT",sym.NOT); }
"||" { return sf.newSymbol("OR",sym.OR); }
"&&" { return sf.newSymbol("AND",sym.AND); }

"==" { return sf.newSymbol("DOUBLE EQUAL",sym.DEQ); }
"!=" { return sf.newSymbol("NOT EQUAL",sym.NEQ); }
"<=" { return sf.newSymbol("LESS OR EQUAL",sym.LESSEQ); }
"<"  { return sf.newSymbol("LESS",sym.LESS); }
">=" { return sf.newSymbol("GREATER OR EQUAL",sym.GTREQ); }
">"  { return sf.newSymbol("GREATER",sym.GTR); }

"="  { return sf.newSymbol("EQUAL",sym.EQ); }

{Identifier} { return sf.newSymbol("Identifier",sym.IDENTIFIER, yytext()); }

[ \t\r\n\f] { /* ignore white space. */ }
. { System.err.println("Illegal character: "+yytext()); }
